package scalalang.reflection

import scala.reflect.runtime.{ universe => ru }
case class Person(n: String)
object Test1 extends App {
  val l = 1 :: 2 :: Nil
  def tag[T: ru.TypeTag](t: T) = ru.typeTag[T]
  val typ = tag(l).tpe
  println(typ)
  val typ2 = ru.typeTag[List[Int]].tpe
  typ2.declarations foreach println
  val typ3 = ru.typeOf[List[Int]]
  //
  val m = ru.runtimeMirror(getClass().getClassLoader())

  val personClass = ru.typeOf[Person].typeSymbol.asClass
  val cm = m.reflectClass(personClass)
  val ctor = ru.typeOf[Person].declaration(ru.nme.CONSTRUCTOR).asMethod
  println(personClass.isCaseClass -> personClass.typeParams)

  val ctorm = cm.reflectConstructor(ctor)
  println(ctorm)
  println(ctorm("tU"))
  //
  case class Purchase(name: String, orderNumber: Int, var shipped: Boolean)
  val shippingTermSymb = ru.typeOf[Purchase].declaration(ru.newTermName("shipped")).asTerm
  val p = Purchase("Jeff Lebowski", 23819, false)
  val im = m.reflect(p)
  println(p)
  val shippingFieldMirror = im.reflectField(shippingTermSymb)
  println(shippingFieldMirror)
  println(shippingFieldMirror.get -> p.shipped)
  shippingFieldMirror.set(true)
  println(shippingFieldMirror.get -> p.shipped)
  //
  class C { val x = 2; var y = 3 }
  val fieldX = ru.typeOf[C].declaration(ru.newTermName("x")).asTerm.accessed.asTerm
  val im2 = m.reflect(new C)
  val fmX = im2.reflectField(fieldX)
  println(fmX.get)
  fmX.set(3) //can hack
  println(fmX.get)
  //

  object CC { def x = 2 }
  val objectC = ru.typeOf[CC.type].termSymbol.asModule
  val mm = m.reflectModule(objectC)
  println(mm.instance)

  //

  /*
 * TypeSymbols
TypeSymbol代表类型、 类和特质的声明，以及类型参数。有趣的成员不能应用到更具体的ClassSymbols，包括isAbstractType， isContravariant和isCovariant.

ClassSymbol： 提供对所有信息包含在类或特质的声明，例如，name、 修饰符 （isFinal、 isPrivate、isProtected、 isAbstractClass等）， baseClasses和typeParams的访问.
TermSymbols
术语符号代表 val、 var、 def，和对象声明，以及软件包和值参数的类型。

MethodSymbol： 方法的类型的符号代表 def 声明 （ TermSymbol的子类）。它支持像检查方法是否是一个 （主） 的构造函数，或一种方法是否支持可变长度参数列表的查询。
ModuleSymbol： 的模块的类型符号代表的对象声明。它允许查找与对象定义成员moduleClass通过隐式关联的类。相反，看着上方也是可能的。一个人可以回去从模块的类相关联的模块的符号通过检查其selfType.termSymbol.
 */

  val type1 = ru.typeOf[Int]
  val type2 = ru.definitions.IntTpe
  println(type1 -> type2)

  //

  class A; class B extends A
  ru.typeOf[A] <:< ru.typeOf[B] //false
  ru.typeOf[B] <:< ru.typeOf[A] //true
  //Byte<:w Short| |Short<:w Int | |Char<:w Int | |Int<:w Long| |Long<:w Float| |Float<:w Double
  ru.typeOf[Int] weak_<:< ru.typeOf[Double] //true

  type Histogram = List[Int]
  ru.typeOf[Histogram] =:= tag(List(4, 5, 6)).tpe //true
  ru.typeOf[Histogram] == tag(List(4, 5, 6)).tpe //false
  import ru._

  //Types.declaration不继承的成员
  //Types.members继承性

  typeOf[List[_]].member("map": TermName) //获取方法
  typeOf[List[_]].member("Self": TypeName) //因为类型成员

 println( showRaw(TypeTree(type1)))

}

